import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.util.Base64;
import java.util.concurrent.ExecutionException;

import nl.martijndwars.webpush.Notification;
import nl.martijndwars.webpush.PushService;
import org.bouncycastle.jce.ECNamedCurveTable;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.jce.spec.ECNamedCurveParameterSpec;
import org.bouncycastle.jce.spec.ECPublicKeySpec;
import org.bouncycastle.math.ec.ECPoint;
import org.jose4j.lang.JoseException;


/**
 * @author:chubiao
 * @description:
 * @date:2022/9/23
 */
public class Subscription {


    private String auth;
    private String key;
    private String endpoint;

    public void setAuth(String auth) {
        this.auth = auth;
    }

    public String getAuth() {
        return auth;
    }

    /**
     * Returns the base64 encoded auth string as a byte[]
     */
    public byte[] getAuthAsBytes() {
        return Base64.getDecoder().decode(getAuth());
    }

    public void setKey(String key) {
        this.key = key;
    }

    public String getKey() {
        return key;
    }

    /**
     * 以字节形式返回base64编码的公钥字符串
     */
    public byte[] getKeyAsBytes() {
        return Base64.getDecoder().decode(getKey());
    }

    /**
     * Returns the base64 encoded public key as a PublicKey object
     */
    public PublicKey getUserPublicKey() throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchProviderException {
        KeyFactory kf = KeyFactory.getInstance("ECDH", BouncyCastleProvider.PROVIDER_NAME);
        ECNamedCurveParameterSpec ecSpec = ECNamedCurveTable.getParameterSpec("secp256r1");
        ECPoint point = ecSpec.getCurve().decodePoint(getKeyAsBytes());
        ECPublicKeySpec pubSpec = new ECPublicKeySpec(point, ecSpec);

        return kf.generatePublic(pubSpec);
    }

    public void setEndpoint(String endpoint) {
        this.endpoint = endpoint;
    }

    public String getEndpoint() {
        return endpoint;
    }

    public Subscription() {
        System.out.println("构造函数");
        // Add BouncyCastle as an algorithm provider
        if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) {
            System.out.println("添加 BouncyCastle 安全提供程序");
            Security.addProvider(new BouncyCastleProvider());
        }
    }


    public static void main(String[] args) throws JoseException, GeneralSecurityException, IOException, ExecutionException, InterruptedException {



        String message = "TmljZSB0cnksIG5vIGtleSBmb3IgeW91IQ==";
        String encode = Base64.getEncoder().encodeToString(message.getBytes(StandardCharsets.UTF_8));
        Subscription sub = new Subscription();
        sub.setAuth("f1JJsvPW2oLK3q3jSgNLnA==");
        sub.setKey("BIJYfntTVG849Na8y0JmAUYl6thIWckBXYQwV1AuvfEHHhxvPO0SQ94ffmGHvQgZ3HXD3zzHecZsKsiGlKJafec=");
        sub.setEndpoint("https://fcm.googleapis.com/fcm/send/cwrYQliPOHA:APA91bEP6C_mZxsiAl38S7sAyUHREQNBgB00PdJYPwehN5m_4eM9wVpHq7LKnhq2NMAIwO667KS1TfzE4svg_TGJxkXfJrfmhEcI6CHkp-Ul2ACzznkkXULglXsWgxyc4cNTib1DDEQj");


        sub.sendPushMessage(sub,"wwwwwwwwwwwwwwwwww".getBytes());

    }

    private static final int TTL = 255;

    public void sendPushMessage(Subscription sub, byte[] payload) throws GeneralSecurityException, JoseException, IOException, ExecutionException, InterruptedException {
        System.out.println("key:"+sub.getUserPublicKey());
        System.out.println("en:"+sub.getEndpoint());
        System.out.println("auth:"+sub.getAuthAsBytes());
        // Figure out if we should use GCM for this notification somehow
//        boolean useGcm = shouldUseGcm(sub);
        Notification notification;
        PushService pushService;

//        if (!useGcm) {
//            // Create a notification with the endpoint, userPublicKey from the subscription and a custom payload
            notification = new Notification(
                    sub.getEndpoint(),
                    sub.getUserPublicKey(),
                    sub.getAuthAsBytes(),
                    payload
            );

            // Instantiate the push service, no need to use an API key for Push API
            pushService = new PushService();
//        } else {
            // Or create a GcmNotification, in case of Google Cloud Messaging
//            notification = new Notification(
//                    sub.getEndpoint(),
//                    sub.getUserPublicKey(),
//                    sub.getAuthAsBytes(),
//                    payload,
//                    TTL
//            );
//
//            // Instantiate the push service with a GCM API key
//            pushService = new PushService("gcm-api-key");
//        }

        // Send the notification
        pushService.send(notification);
    }




}
